home *** CD-ROM | disk | FTP | other *** search
- {
- -----------------------------------------------------------------------------
- Program BMPView; { by Barry Naujok, 1993, written in TP7 }
- { This information was completely derived on my own (ALL of it). }
- { If there are any errors or omisions, please let me know at ... }
- { a1357665@cfs01.cc.monash.edu.au }
- { Currently only supports 3-256 colours (not monochrome or true colour) }
- { My opinion: As can be seen from decoding a BitMaP, I truly believe }
- { that Microsoft is a bit backwards! :) (other opinions welcome) }
-
- Uses VESA,Crt,Dos,Strings;
-
- Const bufsize=32000; { my optimal buffer size, could be bigger for other drives }
- { Has to be even for the RLE decompression }
- Type THeader=Record
- ID : Word; { 'BM' for a Windows BitMaP }
- FSize : LongInt; { Size of file }
- Ver : LongInt; { BMP version (?), currently 0 }
- Image : LongInt; { Offset of image into file }
- Misc : LongInt; { Unknown, appears to be 40 for all files }
- Width : LongInt; { Width of image }
- Height: LongInt; { Height of image }
- Num : Word; { Not sure, possibly number of images or planes (1) }
- Bits : Word; { Number of bits per pixel }
- Comp : LongInt; { Type of compression, 0 for uncompressed, 1,2 for RLE }
- ISize : LongInt; { Size of image in bytes }
- XRes : LongInt; { X dots per metre (not inches! for US, unbelievable!) }
- YRes : LongInt; { Y dots per metre }
- PSize : LongInt; { Palette size (number of colours) if not zero }
- Res : LongInt; { Probably reserved, currently 0 }
- End; { 54 bytes }
-
- PByte = ^Byte;
-
- TPalette = Record
- b,g,r,x : Byte; { BMP uses a fourth byte for the palette, not used }
- End;
-
- Var fl : File;
- header : THeader;
- buffer : PByte;
-
- Procedure BlankPalette;
- Var pal : Array[0..767] Of Byte;
- r : Registers;
- Begin
- FillChar(pal,768,0);
- r.ax:=$1012;
- r.bx:=0;
- r.cx:=256;
- r.dx:=Ofs(pal);
- r.es:=Seg(pal);
- Intr($10,r);
- End;
-
- Procedure SetPalette;
- Const Pal16:Array[0..15]Of Byte=(0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63);
- Var palette : TPalette; { ^ Actual BIOS palette numbers for 16 colour modes }
- BIOSpal : Array[0..767] Of Byte;
- i : Byte;
- r : Registers;
- Begin
- For i:=0 To header.PSize-1 Do Begin
- BlockRead(fl,palette,4);
- If header.PSize>16 Then Begin
- BIOSpal[i*3]:=palette.r Shr 2;
- BIOSpal[i*3+1]:=palette.g Shr 2;
- BIOSpal[i*3+2]:=palette.b Shr 2;
- End Else Begin
- BIOSpal[Pal16[i]*3]:=palette.r Shr 2;
- BIOSpal[Pal16[i]*3+1]:=palette.g Shr 2;
- BIOSpal[Pal16[i]*3+2]:=palette.b Shr 2;
- End;
- End;
- r.ax:=$1012;
- r.bx:=0;
- r.cx:=256;
- r.dx:=Ofs(BIOSpal);
- r.es:=Seg(BIOSpal);
- Intr($10,r);
- End;
-
- Procedure ShowImage256(name:PChar); Assembler;
- Var dseg,width,height,bytes,rows,bank,handle,cp:Word;
- Asm
- Mov dseg,ds
- Mov ax,header.Comp.Word[0]
- Mov cp,ax
- Mov ax,header.Width.Word[0]
- Test ax,1
- Jz @0I
- Inc ax { image is word aligned so adjust width if needed }
- @0I: Mov width,ax
- Mov ax,header.Height.Word[0]
- Mov height,ax
- Mov di,ax
- Dec di
- Mov ax,VesaMode.Bytes
- Mov bytes,ax
- Mov ax,VesaMode.Height
- Mov rows,ax
- Mov es,VesaMode.SegA
-
- Mov ax,$3D00
- Lds dx,name
- Int $21 { Open the file for assembler }
- Mov ds,dseg { Restore the data segment }
- Jc @Ex
- Mov handle,ax
-
- Mov bx,ax
- Mov ax,$4200
- Mov cx,header.Image.Word[2]
- Mov dx,header.Image.Word[0]
- Int $21 { Seek to image location }
- Call @FR
- Jmp @0N
-
- @FR: Push ax
- Push cx
- Push dx
- Mov ds,dseg
- Mov bx,handle
- Mov cx,bufsize
- Lds si,buffer
- Mov dx,si
- Mov ah,$3F
- Int $21
- Mov bx,ax { Bytes left to read from the buffer }
- Pop dx
- Pop cx
- Pop ax
- RetN
-
- @0N: Mov ax,bytes
- Mul di
- Mov di,ax
- Mov bank,dx
- Call @B1 { Set the last line & bank }
- Mov dx,width
-
- Cmp cp,0
- Je @0S
-
- { RLE bitmap }
- @1S: Xor dx,dx { Set DX as the width count }
- @10: Xor ah,ah { Clear upper byte }
- Lodsb { Get "index" byte }
- Dec bx { Decrement buffer count }
- Jnz @11 { Jump if not empty }
- Call @FR { Reload buffer }
- @11: Or al,al
- Jz @14 { Jump if following is a string }
- { Repeat byte }
- Mov cx,ax { else "index" is a repeat count }
- Add dx,cx
- Lodsb { Load data to repeat "index" times }
- Dec bx
- Jnz @12 { Jump if buffer isn't empty }
- Call @FR
- @12: Stosb { Draw byte to screen }
- Or di,di { Check to see if line crosses bank }
- Jnz @13
- Inc bank { Change bank if crossed }
- Call @B1
- @13: Loop @12 { Store all repeated bytes }
- Jmp @10
- { Dump string }
- @14: Lodsb { Load "count", number of bytes in the string }
- Mov cx,ax
- Add dx,cx
- Dec bx
- Jnz @1T { Update buffer count (& buffer contents) }
- Call @FR
- @1T: Or al,al
- Jz @20
- @15: Movsb { Transfer string to screen }
- Or di,di
- Jnz @16 { bank checking }
- Inc bank
- Call @B1
- @16: Dec bx { Update buffer count, etc }
- Jnz @17
- Call @FR
- @17: Loop @15 { Repeat for string }
- Test al,1 { See if there was an odd numbered count }
- Jz @10 { Jump if even }
- Lodsb { Clear extra byte, due to word alignment }
- Dec bx
- Jnz @10 { Update buffer count, etc }
- Call @FR
- Jmp @10
- @20: Sub di,dx { Move screen pointer to start of line }
- Jnc @21 { Jump if not crossed bank }
- Dec bank { Update bank if crossed }
- Call @B1
- @21: Sub di,bytes { Move to screen line above }
- Jnc @23 { Jump if not crossed bank }
- Dec bank { Update bank if crossed }
- Call @B1
- @23: Dec height { Update line count }
- Jnz @1S { Jump to start if not end of the image }
- Jmp @Ex { Exit if image drawn }
-
- { Un-compressed bitmap }
- @0S: Mov cx,dx
- Mov ax,di
- Add ax,cx
- Jc @03 { Jump if line crosses bank }
- Cmp bx,cx
- Jle @03 { Jump if file buffer will run out }
- Sub bx,cx { Update buffer counter }
- Shr cx,1
- Jnc @01
- Movsb
- @01: Rep Movsw { Show line }
- Sub di,dx { Go to next line (above) }
- Sub di,bytes
- Jnc @02
- Dec bank { See if line above is in another bank }
- Call @B1
- @02: Dec height
- Jnz @0S
- Jmp @Ex
- @03: Movsb
- Or di,di
- Jnz @04
- Inc bank
- Call @B1
- @04: Dec bx
- Jnz @05
- Call @FR
- @05: Loop @03
- Sub di,dx
- Jnc @06
- Dec bank
- Call @B1
- @06: Sub di,bytes
- Jnc @07
- Dec bank
- Call @B1
- @07: Dec height
- Jnz @0S
- Jmp @Ex
-
-
- { Set bank }
- @B1: Push ax
- Push ds
- Mov ds,dseg
- Mov al,vesaon
- Or al,al
- Jz @B3
- Push bx
- Push dx
- Mov dx,bank
- Xor bx,bx
- Mov ax,64
- Mul dx
- Div VesaMode.Gran
- Mov dx,ax
- Push dx
- Call VesaMode.WinFunc
- Pop dx
- Inc bx
- Call VesaMode.WinFunc
- Pop dx
- Pop bx
- @B3: Pop ds
- Pop ax
- RetN
- @Ex: Mov ds,dseg
- Mov bx,handle { Close the file }
- Mov ah,$3E
- Int $21
- End;
-
- Procedure ShowImage16(name:PChar); Assembler;
- Var dseg,width,height,bytes,rows,bank,handle,cp,rc,bc:Word;
- Asm
- Mov dseg,ds
- Mov ax,header.Comp.Word[0]
- Mov cp,ax
- Mov ax,header.Width.Word[0]
- Mov width,ax
- Mov ax,header.Height.Word[0]
- Mov height,ax
- Mov di,ax
- Dec di
- Mov ax,VesaMode.Bytes
- Mov bytes,ax
- Mov ax,VesaMode.Height
- Mov rows,ax
- Mov es,VesaMode.SegA
-
- Mov ax,$3D00
- Lds dx,name
- Int $21 { Open the file for assembler }
- Mov ds,dseg { Restore the data segment }
- Jc @Ex
- Mov handle,ax
-
- Mov bx,ax
- Mov ax,$4200
- Mov cx,header.Image.Word[2]
- Mov dx,header.Image.Word[0]
- Int $21 { Seek to image location }
- Call @FR
- Jmp @0N
-
- @FR: Push ax
- Push bx
- Push cx
- Push dx
- Mov ds,dseg
- Mov bx,handle
- Mov cx,bufsize
- Lds si,buffer
- Mov dx,si
- Mov ah,$3F
- Int $21
- Mov bc,ax { Bytes left to read from the buffer }
- Pop dx
- Pop cx
- Pop bx
- Pop ax
- RetN
-
- @0N: Mov ax,bytes
- Mul di
- Mov di,ax
- Mov bank,dx
- Call @B1 { Set the last line & bank }
- Mov dx,$3CE
- Mov ax,$205
- Out dx,ax { Set Write Mode 2 }
- Mov ax,$8008 { Initial bit mask }
-
- Cmp cp,0
- Je @0S
-
- { RLE bitmap }
- @1S: Mov rc,0
- Mov ax,$8008
- @10: Xor ch,ch { Clear upper byte }
- Mov cl,[si] { Get "index" byte }
- Inc si
- Dec bc { Decrement buffer count }
- Jnz @11 { Jump if not empty }
- Call @FR { Reload buffer }
- @11: Or cl,cl
- Jz @14 { Jump if following is a string }
- { Repeat byte }
- Shr cl,1 { Divide the "index" by two }
- Mov bl,[si] { Load data to repeat "index" times }
- Inc si
- Dec bc
- Jnz @12 { Jump if buffer isn't empty }
- Call @FR
- @12: Rol bl,4
- Out dx,ax
- Mov bh,es:[di]
- Mov es:[di],bl { Update screen }
- Ror ah,1
- Jnc @1B
- Inc di
- Jnc @1B
- Inc bank { Change bank if crossed }
- Call @B1
- @1B: Out dx,ax
- Rol bl,4
- Mov bh,es:[di]
- Mov es:[di],bl
- Ror ah,1
- Jnc @13
- Inc di
- Inc rc
- Jnc @13
- Inc bank { Change bank if crossed }
- Call @B1
- @13: Loop @12 { Store all repeated bytes }
- Jmp @10
- { Dump string }
- @14: Mov cl,[si] { Load "count", number of bytes in the string }
- Inc si
- Dec bc
- Jnz @1E { Update buffer count (& buffer contents) }
- Call @FR
- @1E: Or cl,cl
- Jz @20
- Shr cl,1 { Divide the "count" by 2 }
- Push cx
- @15: Mov bl,[si]
- Inc si
- Rol bl,4
- Out dx,ax
- Mov bh,es:[di]
- Mov es:[di],bl
- Ror ah,1
- Jnc @1A
- Inc di
- Jnz @1A { bank checking }
- Inc bank
- Call @B1
- @1A: Out dx,ax
- Rol bl,4
- Mov bh,es:[di]
- Mov es:[di],bl
- Ror ah,1
- Jnc @16
- Inc di
- Inc rc
- Jnz @16
- Inc bank
- Call @B1
- @16: Dec bc { Update buffer count, etc }
- Jnz @17
- Call @FR
- @17: Loop @15 { Repeat for string }
- Pop cx
- Test cl,1 { See if there was an odd numbered count }
- Jz @10 { Jump if even }
- Mov cl,[si] { Clear extra byte, due to word alignment }
- Inc si
- Dec bc
- Jnz @10 { Update buffer count, etc }
- Call @FR
- Jmp @10
- @20: Sub di,rc { Move screen pointer to start of line }
- Jnc @21 { Jump if not crossed bank }
- Dec bank { Update bank if crossed }
- Call @B1
- @21: Sub di,bytes { Move to screen line above }
- Jnc @22 { Jump if not crossed bank }
- Dec bank { Update bank if crossed }
- Call @B1
- @22: Dec height { Update line count }
- Jnz @1S { Jump to start if not end of the image }
- Jmp @Ex { Exit if image drawn }
-
- { Un-compressed bitmap }
- @0S: Mov ax,width
- Xor bx,bx
- Mov rc,ax { Initialize rowcount }
- Mov ax,$8008
- @02: Out dx,ax { Update bit mask register }
- Mov cl,[si] { Load a byte (2 pixels) }
- Inc si { Update buffer pointer }
- Dec bc { Updata buffer count }
- Jnz @03
- Call @FR { Reload buffer if necessary }
- @03: Ror cl,4 { Move 1st pixel in low part of CL }
- Mov ch,es:[di] { Load latches }
- Mov es:[di],cl { Update latches }
- Ror ah,1 { Shift bit mask right a pixel }
- Out dx,ax { Update bit mask register }
- Ror cl,4 { Move 2nd pixel in low part of CL }
- Mov ch,es:[di] { as above 3 steps }
- Mov es:[di],cl { ... }
- Sub rc,2
- Jle @04
- Ror ah,1
- Jnc @02
- Inc di
- Inc bx
- Jnc @02
- Inc bank
- Call @B1
- Jmp @02
- @04: Mov ax,si { Discard extra bytes for }
- Mov cx,4 { LongInt alignment (?) }
- And ax,3
- Sub cx,ax
- And cx,3
- Add si,cx
- Sub bc,cx
- Sub di,bx
- Jnc @06
- Dec bank
- Call @b1
- @06: Sub di,bytes
- Jnc @07
- Dec bank
- Call @b1
- @07: Dec height
- Jnz @0S
- Jmp @Ex
-
- { Set bank }
- @B1: Push ax
- Push ds
- Mov ds,dseg
- Mov al,vesaon
- Or al,al
- Jz @B3
- Push bx
- Push dx
- Mov dx,bank
- Xor bx,bx
- Mov ax,64
- Mul dx
- Div VesaMode.Gran
- Mov dx,ax
- Push dx
- Call VesaMode.WinFunc
- Pop dx
- Inc bx
- Call VesaMode.WinFunc
- Pop dx
- Pop bx
- @B3: Pop ds
- Pop ax
- RetN
- @Ex: Mov ds,dseg
- Mov bx,handle { Close the file }
- Mov ah,$3E
- Int $21
- End;
- Procedure ShowBMP;
- Var fn:Array[0..63]Of Char;
- Begin
- StrPCopy(fn,ParamStr(1));
- GetMem(buffer,bufsize);
- Case header.PSize Of
- 1..16: Begin
- Case header.Width Of
- 0..640 : SetMode($12);
- 641..800 : SetMode($102);
- 801..1024 : SetMode($104);
- 1025..9999 : SetMode($106);
- End;
- BlankPalette;
- ShowImage16(fn);
- End;
- 17..256: Begin
- Case header.Width Of
- 0..320 : SetMode($13);
- 321..640 : SetMode($101);
- 641..800 : SetMode($103);
- 801..1024 : SetMode($105);
- 1025..9999 : SetMode($107);
- End;
- BlankPalette;
- ShowImage256(fn);
- End;
- End;
-
- FreeMem(buffer,bufsize);
- SetPalette;
- Sound(660);
- Delay(100);
- Sound(880);
- Delay(50);
- Sound(440);
- Delay(75);
- NoSound;
-
- ReadKey;
- SetMode(3);
- End;
-
- Procedure SetPSize;
- Begin
- If header.PSize=0 Then Case header.Bits Of
- 1 : header.PSize:=2; { These are the only valid bits in a BMP }
- 4 : header.PSize:=16;
- 8 : header.PSize:=256;
- 24: header.PSize:=0; { A 24 bit image does not have a palette }
- End;
- End;
-
- Begin
- If ParamCount>0 Then Begin
- Assign(fl,ParamStr(1));
- {$I-}
- Reset(fl,1);
- {$I+}
- If IOResult=0 Then Begin
- BlockRead(fl,header,54);
- If header.ID=$4D42 Then Begin
- SetPSize; { Set the PSize field in the header if not defined }
- Writeln;
- Writeln('Width . . . . . ',header.Width,' pixels');
- Writeln('Height . . . . . ',header.Height,' pixels');
- Writeln('Bits per Pixel . ',header.Bits);
- Writeln('Palette Size . . ',header.PSize,' colours, ',header.PSize*4,' bytes');
- Write('Compression . . type ',header.Comp);
- If header.Comp=0 Then Writeln(' (not compressed)')
- Else Writeln(' (RLE)');
- Writeln('Image Offset . . ',header.Image);
- Writeln('Image Size . . . ',header.ISize,' bytes');
- Writeln('X Resolution . . ',header.XRes,' D/m, ',header.XRes*254 Div 10000,' DPI');
- Writeln('Y Resolution . . ',header.YRes,' D/m, ',header.YRes*254 Div 10000,' DPI');
- Writeln;
- If ((header.Width<641)And(header.Height<481)And(header.PSize<17))
- Or((header.Width<321)And(header.Height<201))Or(IsVesa) Then
- If header.PSize>2 Then Begin
- Writeln('Press a key to show the image');
- ReadKey;
- ShowBMP;
- End Else Writeln('Cannot display the image without VESA graphics support');
- Close(fl);
- End Else Writeln('The file is not a Windows BitMaP file');
- End Else Writeln('File not found, try again');
- End Else Writeln('Usage: BMPVIEW <filename>');
- End.
- -----------------------------------------------------------------------------
- Unit VESA;
-
- Interface
-
- Type ModeList=Array[1..32] Of Word; { List of VESA mode numbers }
-
- TVesaMode=Record
- Attr : Word; { Mode Attributes }
- WinA : Byte; { Window A attributes }
- WinB : Byte; { Window B attributes }
- Gran : Word; { Window granularity in K bytes }
- WinSiz : Word; { Size of window in K bytes }
- SegA : Word; { Segment address of window A }
- SegB : Word; { Segment address of window B }
- WinFunc : Procedure; { Windows positioning function }
- Bytes : Word; { Number of bytes per line }
- Width : Word; { Number of horizontal pixels }
- Height : Word; { Number of vertical pixels }
- CharW : Byte; { Width of character cell }
- CharH : Byte; { Height of character cell }
- Planes : Byte; { Number of memory planes }
- Bits : Byte; { Number of bits per pixel }
- nBanks : Byte; { Number of banks (not used) }
- Model : Byte; { Memory model type }
- Banks : Byte; { Size of bank (not used) }
- Pages : Byte; { Number of image pages }
- Reserved : Byte; { The following are for 15,16,24,32 bit colour modes }
- RedMaskSize : Byte; { Size of Red mask in bits }
- RedFieldPos : Byte; { Bit position of LSB of Red mask }
- GreenMaskSize : Byte; { Size of Green mask in bits }
- GreenFieldPos : Byte; { Bit position of LSB of Green mask }
- BlueMaskSize : Byte; { Size of Blue mask in bits }
- BlueFieldPos : Byte; { Bit position of LSB of Blue mask }
- RsvdMaskSize : Byte; { Size of Reserved mask in bits }
- RsvdFieldPos : Byte; { Bit pos. of LSB of Reserved mask }
- DirColModeInf : Byte; { Direct Colour mode attributes }
- Filler : Array[0..215] Of Byte; { Not used - filler }
- End;
-
- TVesaInfo=Record
- Signature : LongInt; { Signature - "VESA" }
- Version : Word; { VESA Version number }
- OEMName : PChar; { Pointer to manufacturer name }
- Capabilities : Longint; { Capabilities (Not used) }
- List : ^ModeList; { Pointer to list of VESA modes }
- TotalMemory : Word; { Number of 64k memory blocks on card }
- Filler : Array[1..238] of Byte;
- End; { 258 byte size due to bug in the Diamond SpeedStar 24X v1.01 BIOS }
-
-
- Var VesaMode : TVesaMode;
- { Contains all info needed for drawing on the screen }
- VesaInfo : TVesaInfo;
- { Contains info on the VESA BIOS Extensions }
-
- vesaon : Byte;
- { Specifies whether a VESA mode is on or not }
-
- Function IsVesa:Boolean;
- { Detects whether VESA support is present }
- Procedure GetVesaInfo;
- { Get Information on VESA modes, etc }
- Procedure GetVesaModeInfo(md:Word);
- { Get Information on a VESA mode (md) }
- Function SetMode(md:Word):Boolean;
- { Sets a video mode (OEM and VESA) }
- Function GetMode:Word;
- { Returns the current video mode }
- Function SizeOfVideoState:Word;
- { Returns the size of the buffer needed to save the video state }
- Procedure SaveVideoState(Var buf);
- { Saves the SVGA video state in the buffer }
- Procedure RestoreVideoState(Var buf);
- { Restores the SVGA video state from the buffer}
- Procedure SetBank(bank:Word);
- { Set the video bank to draw on }
- Function GetBank:Word;
- { Gets the current active video bank }
- Procedure SetLineLength(Var len:Word);
- { Sets the logical scan line length, returns the actual length set }
- Function GetLineLength:Word;
- { Returns the current logical scan line length }
- Procedure SetDisplayStart(pixel,line:Word);
- { Sets the first pixel and line on the display }
- Procedure GetDisplayStart(Var pixel,line:Word);
- { Returns the first pixel and line on the display }
-
- {---------------------------------------------------------------------------}
- {-----------------------------} Implementation {----------------------------}
- {---------------------------------------------------------------------------}
-
- Uses Dos;
-
- Var rp : Registers;
-
- Function IsVesa:Boolean;
- Begin
- rp.ax:=$4F03;
- Intr($10,rp);
- IsVesa:=(rp.al=$4F);
- End;
-
- Procedure GetVesaInfo;
- Begin
- rp.ax:=$4F00;
- rp.di:=Ofs(VesaInfo);
- rp.es:=Seg(VesaInfo);
- Intr($10,rp);
- End;
-
- Procedure GetVesaModeInfo(md:Word);
- Begin
- rp.ax:=$4F01;
- rp.cx:=md;
- rp.di:=Ofs(VesaMode);
- rp.es:=Seg(VesaMode);
- Intr($10,rp);
- End;
-
- Function SetMode(md:Word):Boolean;
- Begin
- SetMode:=True; vesaon:=1;
- If md>$FF Then Begin
- rp.bx:=md;
- rp.ax:=$4F02;
- Intr($10,rp);
- If rp.ax<>$4F Then SetMode:=False Else GetVesaModeInfo(md);
- End Else Begin
- rp.ax:=md;
- Intr($10,rp);
- VesaMode.Gran:=64; vesaon:=0;
- VesaMode.SegA:=$A000;
- Case md Of { OEM (standard) video modes }
- 1..3,7 : Begin { Text modes }
- VesaMode.Width:=80; VesaMode.Height:=25;
- If md=7 Then Begin
- VesaMode.Bits:=1; VesaMode.SegA:=$B000;
- End Else Begin
- VesaMode.Bits:=4; VesaMode.SegA:=$B800;
- End;
- VesaMode.Bytes:=160; VesaMode.Model:=0;
- End;
- $13 : Begin { 320 x 200 x 256 colours, VGA & MCGA }
- VesaMode.Width:=320; VesaMode.Height:=200;
- VesaMode.Bits:=8; VesaMode.Model:=4;
- VesaMode.Bytes:=320;
- End;
- $12 : Begin { 640 x 480 x 16 colours, VGA only }
- VesaMode.Width:=640; VesaMode.Height:=480;
- VesaMode.Bits:=4; VesaMode.Model:=3;
- VesaMode.Bytes:=80;
- End;
- $10 : Begin { 640 x 350 x 16 colours, VGA & EGA with 128k+ }
- VesaMode.Width:=640; VesaMode.Height:=350;
- VesaMode.Bits:=4; VesaMode.Model:=3;
- VesaMode.Bytes:=80;
- End;
- $0E : Begin { 640 x 200 x 16 colours, VGA & EGA }
- VesaMode.Width:=640; VesaMode.Height:=200;
- VesaMode.Bits:=4; VesaMode.Model:=3;
- VesaMode.Bytes:=80;
- End;
- $0D : Begin { 320 x 200 x 16 colours, VGA & EGA }
- VesaMode.Width:=320; VesaMode.Height:=200;
- VesaMode.Bits:=4; VesaMode.Model:=3;
- VesaMode.Bytes:=40;
- End;
- Else SetMode:=False;
- End;
- End;
- End;
-
- Function GetMode:Word;
- Begin
- rp.ax:=$4F03;
- Intr($10,rp);
- GetMode:=rp.bx;
- End;
-
- Function SizeOfVideoState:Word;
- Begin { Will save/restore all video states }
- rp.ax:=$4F04;
- rp.dl:=0;
- rp.cx:=$0F; { hardware, BIOS, DAC & SVGA states }
- Intr($10,rp);
- SizeOfVideoState:=rp.bx;
- End;
-
- Procedure SaveVideoState(Var buf);
- Begin
- rp.ax:=$4F04;
- rp.dl:=1;
- rp.cx:=$0F;
- rp.es:=Seg(buf);
- rp.bx:=Ofs(buf);
- Intr($10,rp);
- End;
-
- Procedure RestoreVideoState(Var buf);
- Begin
- rp.ax:=$4F04;
- rp.dl:=2;
- rp.cx:=$0F;
- rp.es:=Seg(buf);
- rp.bx:=Ofs(buf);
- Intr($10,rp);
- End;
-
- Procedure SetBank(bank:Word);
- Var winnum:Word;
- Begin
- winnum:=bank*64 Div VesaMode.Gran;
- rp.ax:=$4F05;
- rp.bx:=0;
- rp.dx:=winnum;
- Intr($10,rp);
- rp.ax:=$4F05;
- rp.bx:=1;
- rp.dx:=winnum;
- Intr($10,rp);
- End;
-
- Function GetBank:Word;
- Begin
- rp.ax:=$4F05;
- rp.bx:=$100;
- Intr($10,rp);
- GetBank:=rp.dx;
- End;
-
- Procedure SetLineLength(Var len:Word);
- Begin
- rp.ax:=$4F06;
- rp.bl:=0;
- rp.cx:=len;
- Intr($10,rp); { dx:=maximum number of scan lines }
- len:=rp.cx;
- End;
-
- Function GetLineLength:Word;
- Begin
- rp.ax:=$4F06;
- rp.bl:=1;
- Intr($10,rp); { dx:=maximum number of scan lines }
- GetLineLength:=rp.cx;
- End;
-
- Procedure SetDisplayStart(pixel,line:Word);
- Begin
- rp.ax:=$4F07;
- rp.bx:=0;
- rp.cx:=pixel;
- rp.dx:=line;
- Intr($10,rp);
- End;
-
- Procedure GetDisplayStart(Var pixel,line:Word);
- Begin
- rp.ax:=$4F07;
- rp.bx:=1;
- Intr($10,rp);
- pixel:=rp.cx;
- line:=rp.dx;
- End;
-
- End.